package com.coocaa.ops.common.tool.base;

import com.coocaa.ops.common.tool.date.DateUtil;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author tangminghong
 * @date 2020-06-11
 */
public class InstanceUtil {

    /**
     * 获取类的 域的名称 与 域的值  存储在Map中 以供查询使用
     *
     * @param obj
     * @param params
     */
    public static void mappingObject2Map(Object obj, Map<String, Object> params) {
        try {
            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        field.setAccessible(true);
                        return null;
                    }
                });
                if (field.get(obj) instanceof String) {
                    if (StringUtils.isNotBlank(field.get(obj).toString())) {
                        params.put(field.getName(), field.get(obj));
                    }
                } else if (field.get(obj) instanceof Date) {
                    if (field.get(obj) != null) {
                        String date = DateUtil.toLongString((Date) field.get(obj));
                        params.put(field.getName(), date);
                    }
                } else {
                    if (field.get(obj) != null) {
                        params.put(field.getName(), field.get(obj));
                    }
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public static Map<String, String> obj2Map(Object obj) {
        Map<String, String> params = InstanceUtil.newHashMap();
        try {
            Field[] fields;
            Class<?> aClass = obj.getClass();
            for (; aClass != Object.class; aClass = aClass.getSuperclass()) {
                fields = aClass.getDeclaredFields();
                handleObj2Map(obj, fields, params);
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return params;
    }

    private static void handleObj2Map(Object obj, Field[] fields, Map<String, String> params) throws IllegalAccessException {
        for (Field field : fields) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                field.setAccessible(true);
                return null;
            });
            if (field.get(obj) instanceof String) {
                if (StringUtils.isNotBlank(field.get(obj).toString())) {
                    params.put(field.getName(), ((String) field.get(obj)).intern());
                }
            } else if (field.get(obj) instanceof Date) {
                if (field.get(obj) != null) {
                    String date = DateUtil.toLongString((Date) field.get(obj));
                    params.put(field.getName(), date);
                }
            } else {
                if (field.get(obj) != null) {
                    params.put(field.getName(), field.get(obj).toString());
                }
            }
        }
    }

    public static final <E> ArrayList<E> newArrayList() {
        return new ArrayList<>();
    }

    public static final <E> ArrayList<E> newArrayList(int initSize) {
        return new ArrayList<>(initSize);
    }

    public static final <E> ArrayList<E> newArrayList(E... e) {
        ArrayList<E> list = new ArrayList<>();
        Collections.addAll(list, e);
        return list;
    }

    public static final <k, v> HashMap<k, v> newHashMap() {
        return new HashMap<>();
    }

    public static final <k, v> HashMap<k, v> newHashMap(int initSize) {
        return new HashMap<>(initSize);
    }

    public static final <E> HashSet<E> newHashSet() {
        return new HashSet<>();
    }

    public static final <E> HashSet<E> newHashSet(int initSize) {
        return new HashSet<>(initSize);
    }

    public static final <E> HashSet<E> newHashSet(E... e) {
        HashSet<E> set = new HashSet<>();
        Collections.addAll(set, e);
        return set;
    }


    public static final <k, v> Hashtable<k, v> newHashtable() {
        return new Hashtable<>();
    }

    public static final <k, v> LinkedHashMap<k, v> newLinkedHashMap() {
        return new LinkedHashMap<>();
    }

    public static final <E> LinkedHashSet<E> newLinkedHashSet() {
        return new LinkedHashSet<>();
    }

    public static final <E> LinkedList<E> newLinkedList() {
        return new LinkedList<>();
    }

    public static final <k, v> TreeMap<k, v> newTreeMap() {
        return new TreeMap();
    }

    public static final <E> TreeSet<E> newTreeSet() {
        return new TreeSet();
    }

    public static final <E> Vector<E> newVector() {
        return new Vector<>();
    }

    public static final <k, v> WeakHashMap<k, v> newWeakHashMap() {
        return new WeakHashMap<>();
    }

    public static final <k, v> HashMap<k, v> newHashMap(k key, v value) {
        HashMap<k, v> map = newHashMap();
        map.put(key, value);
        return map;
    }

    public static final <k, v> LinkedHashMap<k, v> newLinkedHashMap(k key, v value) {
        LinkedHashMap<k, v> map = newLinkedHashMap();
        map.put(key, value);
        return map;
    }

    public static final <k, v> ConcurrentHashMap<k, v> newConcurrentHashMap() {
        return new ConcurrentHashMap<>();
    }

    public static final <k, v> ConcurrentHashMap<k, v> newConcurrentHashMap(int initSize) {
        return new ConcurrentHashMap<>(initSize);
    }
}
